package com.fyt.reachgo.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fyt.reachgo.domain.Result;
import com.fyt.reachgo.domain.TravelGuide;
import com.fyt.reachgo.service.TravelGuideService;
import com.fyt.reachgo.mapper.TravelGuideMapper;
import com.fyt.reachgo.utils.RedisConstants;
import com.fyt.reachgo.utils.UserHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.fyt.reachgo.utils.RedisConstants.*;

/**
* @author 27675
* @description 针对表【travel_guide(旅行路书信息表（含UGC内容）)】的数据库操作Service实现
* @createDate 2025-02-25 08:37:04
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class TravelGuideServiceImpl extends ServiceImpl<TravelGuideMapper, TravelGuide>
    implements TravelGuideService{

    final private TravelGuideMapper travelGuideMapper;

    final private StringRedisTemplate stringRedisTemplate;

    /**
     * 根据条件查询路书列表
     * @param params
     * @return
     */
    @Override
    public Result getTravelGuideList(Map<String, Object> params) {

        // 查询缓存
        String key = CACHE_TRAVEL_GUIDE_LIST_KEY + params.get("title")
                + ":" + params.get("departureLocation")
                + ":" + params.get("destination") + ":"
                + params.get("days");
        log.debug("缓存key：{}", key);
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))) {// 查看是否存在缓存key
            // 如果存在，则直接返回缓存数据
            String json = stringRedisTemplate.opsForValue().get(key);
            System.out.println("缓存中的路书列表： " + json);
            if (StrUtil.isBlank(json)) {
                // 解决缓存穿透
                return Result.success();
            }
            // json转对象
            List<TravelGuide> travelGuides = JSONUtil.toList(json, TravelGuide.class);
            return Result.success(travelGuides);
        }
        // 缓存不存在，查询数据库
        QueryWrapper<TravelGuide> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .like(StrUtil.isNotBlank(getStr(params, "title")), "title", getStr(params, "title"))
                .like(StrUtil.isNotBlank(getStr(params, "departureLocation")), "departure_location", getStr(params, "departureLocation"))
                .like(StrUtil.isNotBlank(getStr(params, "destination")), "destination", getStr(params, "destination"))
                .eq(StrUtil.isNotBlank(getStr(params, "days")), "days", getStr(params, "days"));

        List<TravelGuide> travelGuides = travelGuideMapper.selectList(queryWrapper);
        if (travelGuides.isEmpty()) {
            // 解决缓存穿透
            stringRedisTemplate.opsForValue().set(key, "",
                    RedisConstants.CACHE_NULL_TTL,
                    TimeUnit.MINUTES);
            return Result.success();
        }
        // 遍历，将content字段转换为json对象
        travelGuides.forEach(guide -> {
            if (guide.getContent() != null) {
                guide.setContent(JSONUtil.parseObj(guide.getContent()));
            }
        });
        // 缓存结果到redis,随机时间，解决缓存雪崩
        stringRedisTemplate.opsForValue().set(
                key,
                JSONUtil.toJsonStr(travelGuides),
                RedisConstants.CACHE_TTL + RandomUtil.randomLong(20),
                TimeUnit.MINUTES);

        System.out.println("搜索到的路书列表： " + travelGuides);
        return Result.success(travelGuides);
    }

    /**
     * 根据id查询路书详情
     * @param params
     * @return
     */
    @Override
    public Result getTravelGuideById(Map<String, Object> params) {

        if (!params.containsKey("id")) {
            return Result.error("参数错误");
        }
        System.out.println("id: " + params.get("id"));
        Long id = Long.parseLong(params.get("id").toString());
        String key = CACHE_TRAVEL_GUIDE_KEY + params.get("id");
        // 查询缓存
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))){
            // 如果缓存存在
            String json = stringRedisTemplate.opsForValue().get(key);
            if (StrUtil.isBlank(json)) {
                // 解决缓存穿透
                return Result.success();
            }
            // json转对象
            TravelGuide travelGuide = JSONUtil.toBean(json, TravelGuide.class);
            // 直接返回缓存数据
            return Result.success(travelGuide);
        }
        // 缓存不存在，查询数据库
        TravelGuide travelGuide = travelGuideMapper.selectById(id);
        if (travelGuide == null) {
            // 解决缓存穿透
            stringRedisTemplate.opsForValue().set(key, "",
                    RedisConstants.CACHE_NULL_TTL,
                    TimeUnit.MINUTES);
            return Result.success();
        }
        travelGuide.setContent(JSONUtil.parseObj(travelGuide.getContent()));
        stringRedisTemplate.opsForValue().set(
                key,
                JSONUtil.toJsonStr(travelGuide),
                RedisConstants.CACHE_TTL + RandomUtil.randomLong(20),
                TimeUnit.MINUTES);
        return Result.success(travelGuide);
    }

    @Override
    public Result tanTList() {
        Long userId = UserHolder.getUser().getUserId();
        List<TravelGuide> travelGuides = travelGuideMapper.tanTList(userId);

        return Result.success(travelGuides);
    }

    private String getStr(Map<String, Object> params, String key) {
        if (!params.containsKey(key)) return "";
        Object value = params.get(key);
        return value != null ? value.toString().trim() : "";
    }


}




